/* eslint-disable */
<template>
  <el-form :ref="form" :model="params" :inline="inline" :size="size" :label-width="labelWidth ? (labelWidth + 'px') : ''" @submit.native.prevent="searchHandler()">
    <el-row>
      <el-col v-for="(form, index) in forms" :sm="form.sm || 24" :md="12" :lg="form.md || 11" :key="index">
        <div v-show="!form.status">
          <el-form-item :prop="form.itemType != 'daterange' ? form.prop : (datePrefix + index)" :label="$t(form.label)" :rules="form.rules || []" :label-width="form.labelWidth ? (form.labelWidth + 'px') : ''">
            <el-input v-if="form.itemType === 'input' || form.itemType === undefined" v-model="params[form.prop]" :readonly="form.readonly" :disabled="form.disabled" :placeholder="form.placeholder || $t('placeholder.input')" :style="itemStyle + (form.itemWidth ? `width: ${form.itemWidth}px;` : '')" clearable />
            <el-select v-else-if="form.itemType === 'select'" v-model="params[form.prop]" :disabled="form.disabled" :placeholder="form.placeholder || $t('placeholder.select')" :style="itemStyle + (form.itemWidth ? `width: ${form.itemWidth}px;` : '')" clearable>
              <el-option v-for="(option, optionIndex) in form.options" :key="optionIndex + '_local'" :value="(typeof option === 'object') ? option[form.valueKey || 'value'] : option" :label="(typeof option === 'object') ? $t(option[form.labelKey || 'label']) : $t(option)" >
                <!-- <slot name="select" /> -->
              </el-option>
              <!-- <el-option v-for="(op, opIndex) in selectOptions[selectOptionPrefix + index]" :key="opIndex + '_remote'" :value="(typeof op === 'object') ? op[form.valueKey || 'value'] : op" :label="(typeof op === 'object') ? op[form.labelKey || 'label'] : op" /> -->
            </el-select>
            <el-date-picker v-else-if="form.itemType === 'date'" v-model="params[form.prop]" :placeholder="form.placeholder" :disabled="form.disabled" :readonly="form.readonly" :editable="form.editable" :style="itemStyle + (form.itemWidth ? `width: ${form.itemWidth}px;` : '')" :picker-options="form.pickerOptions || {}" type="date" />
            <el-date-picker
              v-else-if="form.itemType === 'daterange'"
              v-model="params[form.modelValues]"
              :disabled="form.disabled"
              :readonly="form.readonly"
              :editable="form.editable"
              :placeholder="form.placeholder"
              :start-placeholder="$t('placeholder.start')"
              :end-placeholder="$t('placeholder.end')"
              :default-time="['00:00:00', '23:59:59']"
              :style="itemStyle + (form.itemWidth ? `width: ${form.itemWidth}px;` : '')"
              :picker-options="form.pickerOptions || {}"
              :value-format="form.pickerOptions"
              type="daterange"
              @change="date => changeDate(date, form.prop[0], form.prop[1], index)" />
            <el-input-number v-else-if="form.itemType === 'number'" v-model="params[form.prop]" :min="1" controls-position="right" @change="handleChange" />
            <el-switch v-else-if="form.itemType === 'swith'" v-model="params[form.prop]" :active-value="1" :inactive-value="0" />
            <el-radio-group v-else-if="form.itemType === 'radio'" v-model="params[form.prop]">
              <el-radio v-for="(option,optionIndex) in form.options" :key="optionIndex" :label="option.label">{{ option.label }}</el-radio>
            </el-radio-group>
          </el-form-item>
        </div>
      </el-col>
      <!-- </el-row> -->
      <el-col v-if="dialog" :sm="24" :md="24" :lg="btnMd">
        <el-row :justify="btnJustify" type="flex">
          <el-form-item label-width="50px">
            <el-button v-if="showSearchBtn" :loading="submitLoading" type="primary" size="small" @click="searchHandler">
              {{ submitBtnText|| $t('btn.search') }}
            </el-button>
            <el-button v-if="showResetBtn" :loading="submitLoading" type="info" size="small" @click="resetForm">
              {{ resetBtnText || $t('btn.reset') }}
            </el-button>
            <el-button v-if="showDownloadBtn" :loading="downloadLoading" class="filter-item" type="danger" plain size="small" @click="handleDownload">{{ $t('btn.export') }}
            </el-button>
            <!-- <el-button
              v-if="showDownloadBtn"
              :loading="downloadLoading"
              class="filter-item"
              type="primary"
              size="small"
              icon="el-icon-download"
              @click="handleDownload">{{ $t('btn.export') }}
            </el-button> -->
            <slot name="btn" />
          </el-form-item>
        </el-row>
      </el-col>
    </el-row>
  </el-form>
</template>

<script>
import { formProps } from './props'
export default {
  name: 'ElSearchForm',
  props: formProps,
  data() {
    const { forms, fuzzy } = this.$props
    const datePrefix = 'daterange-prefix'
    const selectOptionPrefix = 'select-option-prefix'
    const dataObj = {
      selectOptions: {}
    }

    const params = {}
    const format = {}
    const fuzzyOps = {}

    forms.forEach((v, i) => {
      const propType = typeof v.prop
      if (propType === 'string') {
        // v.modelValue = v.prop
        params[v.prop] = v.modelValue
        fuzzyOps[v.prop] = v.fuzzy ? v.fuzzy : fuzzy
        if (v.format) {
          format[v.prop] = v.format
        }
      } else if (propType === 'object' && Object.prototype.toString.call(v.prop) === '[object Array]') {
        v.prop.forEach(vv => {
          params[vv] = ''
          if (v.format) {
            format[vv] = v.format
          }
          fuzzyOps[vv] = v.fuzzy ? v.fuzzy : v.formatfuzzy
        })
      }
      if (v.itemType === 'daterange') {
        // params[datePrefix + i] = ''
        // v.modelValue = datePrefix + i
        params[datePrefix + i] = v.modelValue
        v.modelValues = datePrefix + i
        if (v.modelValue) {
          const firstDate = v.modelValue[0]
          const secondDate = v.modelValue[1]
          const dates = [
            (firstDate.getTime() + firstDate.getTimezoneOffset() * 60 * 1000) / 1000,
            (secondDate.getTime() + secondDate.getTimezoneOffset() * 60 * 1000) / 1000
          // `${firstDate.getFullYear()}-${('0' + (firstDate.getMonth() + 1)).substr(-2)}-${('0' + firstDate.getDate()).substr(-2)}`,
          // `${secondDate.getFullYear()}-${('0' + (secondDate.getMonth() + 1)).substr(-2)}-${('0' + secondDate.getDate()).substr(-2)}`
          ]
          params[v.prop[0]] = dates[0]
          params[v.prop[1]] = dates[1]
          // fuzzyOps[v.prop[1]] = v.prop[1].fuzzy ? v.prop[1].fuzzy : fuzzy
          // fuzzyOps[v.prop[0]] = v.prop[0].fuzzy ? v.prop[0].fuzzy : fuzzy
        }
      }
      if (v.itemType === 'select' && (v.selectFetch || v.selectUrl)) {
        const dataKey = selectOptionPrefix + i
        dataObj.selectOptions[dataKey] = []
        const { $axios } = this
        if (!v.selectMethod) {
          v.selectMethod = 'get'
        }
        this.getRemoteData({
          fetch: v.selectFetch ? v.selectFetch : () => {
            return $axios[v.selectMethod](v.selectUrl, v.selectMethod.toLowerCase() === 'get'
              ? { params: v.selectParams } : v.selectParams)
          },
          dataKey,
          resultField: v.selectResultField || 'result',
          resultHandler: v.selectResultHandler
        })
      }
    })

    return {
      params,
      datePrefix,
      selectOptionPrefix,
      ...dataObj,
      format,
      fuzzyOps
    }
  },
  computed: {
    itemStyle() {
      const { itemWidth } = this
      if (itemWidth) {
        return `width: ${itemWidth}px;`
      }
      return ''
    },
    lang() {
      return this.$store.getters.language
    }
  },
  watch: {
    // lang() {
    //   this.params = this.params
    // }
  },
  mounted() {
  },
  methods: {
    handleChange(value) {
    },
    isArray(value) {
      return typeof value === 'object' && Object.prototype.toString.call(value) === '[object Array]'
    },
    searchHandler() {
      this.getParams((error, params) => {
        if (!error) {
          const { submitHandler } = this
          if (submitHandler) {
            submitHandler(params)
          } else {
            throw new Error('Need to set attribute: submitHandler !')
          }
        }
      })
    },
    getParamFuzzy() {
      return this.fuzzyOps
    },
    getParams(callback) {
      this.$refs.form.validate(valid => {
        if (valid) {
          const { params, datePrefix, format } = this
          const formattedForm = {}
          Object.keys(params).forEach(v => {
            if (v.indexOf(datePrefix) === -1) {
              formattedForm[v] = format[v] ? format[v](params[v], v) : params[v]
            }
          })
          if (callback) callback(null, formattedForm)
        } else {
          if (callback) callback(new Error())
        }
      })
    },
    resetForm() {
      this.$emit('reset')
      this.$refs.form.resetFields()
      const datePrefix = 'daterange-prefix'
      this.forms.forEach((v, i) => {
        if (v.itemType === 'daterange') {
          this.params[datePrefix + i] = v.modelValue
          v.modelValues = datePrefix + i
          if (v.modelValue) {
            const firstDate = v.modelValue[0]
            const secondDate = v.modelValue[1]
            const dates = [
              (firstDate.getTime() + firstDate.getTimezoneOffset() * 60 * 1000) / 1000,
              (secondDate.getTime() + secondDate.getTimezoneOffset() * 60 * 1000) / 1000
            ]
            this.params[v.prop[0]] = dates[0]
            this.params[v.prop[1]] = dates[1]
          } else {
            this.params[v.prop[0]] = undefined
            this.params[v.prop[1]] = undefined
          }
        }
      })
    },
    changeDate(date, startDate, endDate, i) {
      let dates

      if (date === null) {
        this.params[startDate] = ''
        this.params[endDate] = ''
        return
      }
      if (typeof date === 'string') {
        dates = date.split(' - ')
      } else if (date && date.hasOwnProperty('length')) {
        const firstDate = date[0]
        const secondDate = date[1]
        dates = [
          (firstDate.getTime() + firstDate.getTimezoneOffset() * 60 * 1000) / 1000,
          (secondDate.getTime() + secondDate.getTimezoneOffset() * 60 * 1000) / 1000
          // `${firstDate.getFullYear()}-${('0' + (firstDate.getMonth() + 1)).substr(-2)}-${('0' + firstDate.getDate()).substr(-2)}`,
          // `${secondDate.getFullYear()}-${('0' + (secondDate.getMonth() + 1)).substr(-2)}-${('0' + secondDate.getDate()).substr(-2)}`
        ]
      }

      this.params[startDate] = dates[0]
      this.params[endDate] = dates[1]
    },
    getRemoteData({ fetch, dataKey, resultField, resultHandler }) {
      fetch().then(response => {
        let result = response
        if (typeof response === 'object' && !this.isArray(response)) {
          if (resultField.indexOf('.') !== -1) {
            resultField.split('.').forEach(vv => {
              result = result[vv]
            })
          } else {
            result = response[resultField]
          }
        }

        if (!result || !(result instanceof Array)) {
          console.warn(`The result of key:${resultField} is not Array. 接口返回的字段:${resultField} 不是一个数组`)
        }

        if (this.resultHandler) {
          this.selectOptions[dataKey] = result.map(this.resultHandler)
        } else {
          this.selectOptions[dataKey] = result
        }
      })
    },
    handleDownload() {
      const { url } = this
      const baseURL = process.env.NODE_ENV === 'development' || 'local' ? '/api' : process.env.BASE_API // api 的 base_url
      this.getParams((error, params) => {
        if (!error) {
          let str = ''
          for (const key in params) {
            if (params.hasOwnProperty(key) && params[key]) {
              str += '&' + key + '=' + params[key]
            }
          }
          window.location.href = `${baseURL}${url}?export_tag=1${str}`
        }
      })
    }
  }
}
</script>
